/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package icontrole.core;

import br.ufrn.dca.controle.QuanserClient;
import br.ufrn.dca.controle.QuanserClientException;
import java.text.DecimalFormat;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author heliojr
 */
public class ServerQuanser extends Observable implements Runnable {

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    private QuanserClient _client;
    private Double _constank1;
    private Double _constank2;
    private String _ip;
    private String _port;
    private String _nivel;
    private double _nivel_tk1;
    private double _nivel_tk2;
    private double _sinalControle;
    private double _sinalErro;
    private String _name;
    private String _path;
    private String _path_name;
    private boolean _state;
    private boolean _operation;
    private Thread _timer;
    //Parametros de desempenho
    private double _sobresinal;
    //Tempos
    private double _tempoDePico;
    private double _tempodeAcomodacao;
    private double _Acomodacao;

    public double getAcomodacao() {
        return _Acomodacao;
    }

    public void setAcomodacao(double _Acomodacao) {
        this._Acomodacao = _Acomodacao;
    }
    private double _tempoSubida;

    public double getSobresinal() {
        return _sobresinal;
    }

    public void setSobresinal(double _sobresinal) {
        this._sobresinal = _sobresinal;
    }

    public ServerQuanser() {
        this._constank1 = 0.0;
        this._constank2 = 0.0;
        this._sobresinal = 0.0;
        this._tempoSubida = 0.0;
        this._tempoDePico = 0.0;
        this._state = false;
        this._operation = false;

    }

    public void Connect() {
        try {

            _client = new QuanserClient(_ip, Integer.parseInt(_port));

        } catch (Exception ex) {
            System.out.println(" Erro Conexao com o quanser!");
        }
    }

    public double tensaoLimitada(double dado) {
        if (dado > 3.0) {
            dado = 3.0;
        } else if (dado < 0.0) {
            dado = 0.0;
        }
        return dado;
    }

    public synchronized void escrever(double dado, int canal) {
        try {
            _client.write(canal, tensaoLimitada(enxuga(dado)));
        } catch (QuanserClientException ex) {
            System.out.println(" Erro escrever com o quanser!");
        }
    }

    public Double enxuga(double numero) {
        Double db = 0.0;
        String form = "";
        try {


            DecimalFormat format = new DecimalFormat();
            format.setMinimumFractionDigits(2);
            format.setMaximumFractionDigits(2);
            form = format.format(numero);
            db = Double.parseDouble(form.replace(",", "."));

        } catch (Exception e) {
String text = form;
        }
        return db;

    }

    public double constanteTanque(int canal) {
        if (canal == 0) {
            return _constank1;
        } else {
            return _constank2;
        }
    }

    public synchronized double ler(int canal) {
        try {
            Double value = _client.read(canal) * constanteTanque(canal);
            double s = enxuga(value);
            System.out.println("Dado do canal " + canal + " : " + value + ";");
            if (s >= 20.0) {
                _client.write(0, 0.0);
            }
            return s;
        } catch (QuanserClientException ex) {
            System.out.println(" Erro ler com o quanser!");
        }
        return -1;
    }

    public synchronized boolean parar() {
        boolean parou = false;

        try {
            _client.write(0, 0);
            parou = true;

        } catch (QuanserClientException ex) {
            System.out.println(" Erro parar com o quanser!");
        }
        return parou;
    }

    public void run() {

        _timer = new Thread() {

            @Override
            public void run() {
                super.run();
                while (true) {
                    Updating();
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(ServerQuanser.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        };
        _timer.start();

    }

    public void Updating() {
        setChanged();
        notifyObservers();
    }

    public void StopServer() throws InterruptedException {
        this._timer.stop();
        this._state = false;
        this._operation = false;
        escrever(0.0, 0);

    }

    public void StartServer() {
        if (this._state == false) {
            this.Connect();
            this._state = true;
            this._operation = true;
        }
        run();
    }

    public void StartServer(boolean operation) {
        if (this._state == false) {
            this.Connect();
            this._state = true;
            this._operation = operation;
        }
        run();
    }

    public String getNivel() {
        return _nivel;
    }

    public void setNivel(String _Nivel) {
        this._nivel = _Nivel;
    }

    public String getIp() {
        return _ip;
    }

    public void setIp(String _Ip) {
        this._ip = _Ip;

    }

    public String getPort() {
        return _port;
    }

    public void setPort(String Port) {
        this._port = Port;

    }

    public double getNivel_tk1() {

        return _nivel_tk1;
    }

    public void setNivel_tk1(double _nivel_tk1) {

        this._nivel_tk1 = _nivel_tk1;

        // notifica todos os observadores que esse objeto foi alterado

    }

    public double getNivel_tk2() {
        return _nivel_tk2;
    }

    public void setNivel_tk2(double _nivel_tk2) {
        // notifica todos os observadores que esse objeto foi alterado  
        this._nivel_tk2 = _nivel_tk2;

    }

    public double getSinalControle() {
        return _sinalControle;
    }

    public void setSinalControle(double _sinalControle) {
        this._sinalControle = _sinalControle;
    }

    public double getSinalErro() {
        return _sinalErro;
    }

    public void setSinalErro(double _sinalErro) {
        this._sinalErro = _sinalErro;
    }

    public QuanserClient getClient() {
        return _client;
    }

    public void setClient(QuanserClient _client) {
        this._client = _client;
    }

    public Double getConstank1() {
        return _constank1;
    }

    public void setConstank1(double _constank) {
        this._constank1 = _constank;
    }

    public String getName() {
        return _name;
    }

    public void setName(String _name) {
        this._name = _name;
    }

    public String getPath() {
        return _path;
    }

    public void setPath(String _path) {
        this._path = _path;
    }

    public String getPath_name() {
        return _path_name;
    }

    public void setPath_name(String _path_name) {
        this._path_name = _path_name;
    }

    private void Inicialize(ServerQuanser Quanser) {
        this._client = Quanser.getClient();
        this._constank1 = Quanser.getConstank1();
        this._constank2 = Quanser.getConstank2();
        this._ip = Quanser.getIp();
        this._nivel = Quanser.getNivel();
        this._nivel_tk1 = Quanser.getNivel_tk1();
        this._nivel_tk2 = Quanser.getNivel_tk2();
        this._path = Quanser.getPath();
        this._path_name = Quanser.getPath_name();
        this._port = Quanser.getPort();
        this._sinalControle = Quanser.getSinalControle();
        this._sinalErro = Quanser.getSinalErro();


    }

    public boolean isOperation() {
        return _operation;
    }

    public void setOperation(boolean _operation) {
        this._operation = _operation;
    }

    /**
     * @return the _constank2
     */
    public Double getConstank2() {
        return _constank2;
    }

    /**
     * @param constank2 the _constank2 to set
     */
    public void setConstank2(double constank2) {
        this._constank2 = constank2;
    }

    public String ShowTempoDePico() {
        return (enxuga(_tempoDePico).toString() + "");
    }

    /**
     * @return the tempoDePico
     */
    public double getTempoDePico() {
        return _tempoDePico;
    }

    /**
     * @param tempoDePico the tempoDePico to set
     */
    public void setTempoDePico(double tempoDePico) {
        this._tempoDePico = tempoDePico;
    }

    /**
     * @return the tempodeAcomodacao
     */
    public double getTempodeAcomodacao() {
        return _tempodeAcomodacao;
    }

    /**
     * @param tempodeAcomodacao the tempodeAcomodacao to set
     */
    public void setTempodeAcomodacao(double tempodeAcomodacao) {
        this._tempodeAcomodacao = tempodeAcomodacao;
    }

    /**
     * @return the tempoSubida
     */
    public double getTempoSubida() {
        return _tempoSubida;
    }

    /**
     * @param tempoSubida the tempoSubida to set
     */
    public void setTempoSubida(double tempoSubida) {
        this._tempoSubida = tempoSubida;
    }

    public String showTempoSubida() {
        return enxuga(getTempoSubida()).toString();
    }

    public String showTempoAcomodacao() {
        return enxuga(getTempodeAcomodacao()).toString();
    }
}
